package params

import (
	"demo/util"
	"github.com/gin-gonic/gin"
)

type Login struct {
	User     string `form:"user" binding:"required"`
	Password string `form:"password" binding:"required"`
}

type UserInfo struct {
	userId string
}

var loginMap = make(map[string]*UserInfo, 0)

//服务端记录登录状态，并向客户端设置cookie
func recordLogin(login Login, c *gin.Context) bool {
	uid := login.User
	password := login.Password

	if len(uid) == 0 || len(password) == 0 {
		return false
	}

	if password != "pass"+uid {
		return false
	}

	//服务端记录状态
	userMd5 := util.Md5(uid)
	loginMap[userMd5] = &UserInfo{userId: uid}

	/**
	设置cookie cookie参数如下：
	name   名称
	value  值
	maxAge 过期时间
	path   路径，默认为/
	domain 域名，默认为http请求的host
	secure 是否工作在安全模式。设置为true，只有https请求，浏览器才保存cookie
	httpOnly  是否只有http请求能携带cookie。设置为true，ajax请求无法携带cookie
	*/
	maxAge := 7 * 24 * 3600
	c.SetCookie("login-token", userMd5, maxAge, "/", "", false, false)
	return true
}

//校验登录状态
func CheckLogin(c *gin.Context) *UserInfo {
	//检测cookie
	loginToken, err := c.Cookie("login-token")
	if err == nil {
		userInfo := loginMap[loginToken]
		return userInfo
	} else {
		//检测请求参数
		loginToken := c.Query("login-token")
		if len(loginToken) == 0 {
			loginToken = c.PostForm("login-token")
		}

		if len(loginToken) > 0 {
			return loginMap[loginToken]
		} else {
			return nil
		}
	}
}

func BindRoute(r gin.IRouter) {
	//gin框架根据content-type类型，自动提取相应格式的参数
	//json参数
	r.POST("/loginJson", func(c *gin.Context) {
		var login Login
		if err := c.ShouldBind(&login); err != nil {
			c.JSON(500, gin.H{
				"message": err.Error(),
			})
			return
		}

		//记录登录状态
		if recordLogin(login, c) {
			c.JSON(200, gin.H{
				"message": "login success",
			})
		} else {
			c.JSON(200, gin.H{
				"message": "login failed",
			})
		}
	})

	//form参数
	r.POST("/loginForm", func(c *gin.Context) {
		var login Login
		if err := c.ShouldBind(&login); err != nil {
			c.JSON(500, gin.H{
				"message": err.Error(),
			})
			return
		}

		//记录登录状态
		if recordLogin(login, c) {
			c.JSON(200, gin.H{
				"message": "login success",
			})
		} else {
			c.JSON(200, gin.H{
				"message": "login failed",
			})
		}
	})

	//get url参数
	r.GET("/loginParam", func(c *gin.Context) {
		var login Login
		if err := c.ShouldBind(&login); err != nil {
			c.JSON(500, gin.H{
				"message": err.Error(),
			})
			return
		}

		//记录登录状态
		if recordLogin(login, c) {
			c.JSON(200, gin.H{
				"message": "login success",
			})
		} else {
			c.JSON(200, gin.H{
				"message": "login failed",
			})
		}
	})

	r.GET("/listLogin", func(c *gin.Context) {
		c.JSON(200, loginMap)
	})

	r.GET("/logout", func(c *gin.Context) {
		loginToken, _ := c.Cookie("login-token")
		c.SetCookie("login-token", "", -1, "/", "", false, false)

		delete(loginMap, loginToken)
		c.JSON(200, gin.H{
			"message": "logout",
		})
	})
}
